var defaultParent = null;

function ajax_replace_node() {

    xml = this.responseXML;

    var errorpath = window.location.protocol + '//' + window.location.hostname + ((window.location.port == '') ? '' : ':' + window.location.port) + window.location.pathname;
    var trace = window.location.href.match(/\?_trc=[^&]*/);
    if (trace && trace.length > 0)
        errorpath += trace[0];


    if (xml == null)
        window.location.href = errorpath;

    if (xml.getElementsByTagName('replace').length == 0)
        window.location.href = errorpath;

    var eltoId = xml.getElementsByTagName('replace')[0].firstChild.nodeValue;
    if (eltoId == null)
        window.location.href = errorpath;

    var jsCode = xml.getElementsByTagName('javascript')[0].firstChild.nodeValue;
    var htmlCode = xml.getElementsByTagName('body')[0].firstChild.nodeValue;

    //el problema del codigo html es que también tiene el Id por lo que sería conveniente eliminar primero el otro

    var elto = document.getElementById(eltoId);
//alert(eltoId);
    if (elto == null)
        window.location.href = errorpath;

    //aqui ya puedo llamar a la funcion de smooth... o mejot dejarlo para el final


    var pater = elto.parentNode;
    var next = elto.nextSibling; //Y si no tiene next

    pater.removeChild(elto);


    var parteScript = htmlCode.indexOf('<script') == 0;
    var partes = htmlCode.split(/<\/?script[^>]*>/ig); //esto me lo dejaría dividido por los campos

    var stdOut = '';

    var f = document.write;
    document.write = function(str) {
        stdOut += str;
    }

    defaultParent = eltoId;
    eval(jsCode);

    //bien, aqui quedarán registrados todos los nodos

    for (var i = 0; i < partes.length; i++) {

        if (parteScript)
            eval(partes[i].replace('<!--', '').replace('-->', ''));

        else
            stdOut += partes[i];

        parteScript = !parteScript;
    }

    document.write = f;

    //tengo que extraer las partes script y ejecutarlas por separado con especial cuidado con los document.write()
    //Cambio el document.write('...'); por stdOut+='';
    var aux = document.createElement('DIV');
    document.body.appendChild(aux);
    aux.style.display = 'none';


    while (stdOut.charAt(0) == ' ')
        stdOut = stdOut.substring(1);

    if (stdOut.toUpperCase().indexOf('<TD') == 0)
        aux.innerHTML = '<table><tbody><tr>' + stdOut + '</tr></tbody></table>';

    else if (stdOut.toUpperCase().indexOf('<TR') == 0)
        aux.innerHTML = '<table><tbody>' + stdOut + '</tbody></table>';

    else if (stdOut.toUpperCase().indexOf('<LI') == 0)
        aux.innerHTML = '<ul>' + stdOut + '</ul>';

    else
        aux.innerHTML = stdOut;


    elto = document.getElementById(eltoId);

    if (next)
        pater.insertBefore(elto, next);
    else
        pater.appendChild(elto);

    document.body.removeChild(aux);

    this.ajaxizeForms();

    XMLHttpRequest.sendQueued();
}

function ajax_transition() {

    var elto = document.getElementById(this._loading_node_id);

    if (document.all)
        elto.style.filter = 'alpha(opacity=30)';
    else
        elto.style.opacity = 0.3;

    var iReturnValue = 0;
    while (elto != null) {
        iReturnValue += elto.offsetTop;
        elto = elto.offsetParent;
    }

    var scrollPos;
    if (self.pageYOffset)
        scrollPos = self.pageYOffset;
    // Internet Explorer 6 - standards mode
    else if (document.documentElement && document.documentElement.scrollTop)
        scrollPos = document.documentElement.scrollTop;
    // Internet Explorer 6, 7 and 8
    else if (document.body.scrollTop)
        scrollPos = document.body.scrollTop;


    if (scrollPos > iReturnValue)
        smoothScroll(iReturnValue);
}

function ajax_on_change_state() {
    if (this.readyState == XMLHttpRequest.LOADING && this.onreadystateloading)
        this.onreadystateloading();

    if (this.readyState == XMLHttpRequest.LOADING && this.onreadystatedone)
        this.onreadystatedone();
}


function currentYPosition() {

    // Firefox, Chrome, Opera, Safari

    if (self.pageYOffset)
        return self.pageYOffset;

    // Internet Explorer 6 - standards mode

    if (document.documentElement && document.documentElement.scrollTop)
        return document.documentElement.scrollTop;

    // Internet Explorer 6, 7 and 8

    if (document.body.scrollTop)
        return document.body.scrollTop;

    return 0;

}

function smoothScroll(stopY) {

    var startY = currentYPosition();

    var distance = stopY > startY ? stopY - startY : startY - stopY;

    if (distance < 100) {

        scrollTo(0, stopY);
        return;

    }
    var speed = Math.round(distance / 100);

    if (speed >= 20)
        speed = 20;

    var step = Math.round(distance / 25);

    var leapY = stopY > startY ? startY + step : startY - step;

    var timer = 0;
    if (stopY > startY) {

        for (var i = startY; i < stopY; i += step) {

            setTimeout("window.scrollTo(0, " + leapY + ")", timer * speed);

            leapY += step;
            if (leapY > stopY)
                leapY = stopY;
            timer++;

        }
        return;

    }
    for (var i = startY; i > stopY; i -= step) {
        setTimeout("window.scrollTo(0, " + leapY + ")", timer * speed);

        leapY -= step;
        if (leapY < stopY)
            leapY = stopY;
        timer++;

    }

}


XMLHttpRequest._insertInQueue = true;
XMLHttpRequest._queue = new Array();

XMLHttpRequest.prototype._oldSend = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.send = function(vData) {

    if (XMLHttpRequest._insertInQueue)
        XMLHttpRequest._queue[XMLHttpRequest._queue.length] = {object: this, data: vData};

    else {
        if (this._loading_node_id != null && !XMLHttpRequest._insertInQueue)
            XMLHttpRequest._insertInQueue = true;

        this._oldSend(vData);
    }

}

XMLHttpRequest.sendQueued = function() {
    XMLHttpRequest._insertInQueue = false;

    for (var i = 0; i < this._queue.length; i++)
        this._queue[i].object.send(this._queue[i].data);

    this._queue = new Array();
}


XMLHttpRequest.prototype.ajaxizeForms = function() {

    var forms = document.getElementsByTagName("FORM");

    for (var i = 0; i < forms.length; i++)
        if (forms[i]._ajaxized) {

        }
        else {

            var replace = null;

            for (j = 0; j < forms[i].elements.length; j++)
                if (forms[i].elements[j].name == '_asyncId') {

                    replace = forms[i].elements[j].value;

                    if (document.getElementById(replace)) {
                        var elto = document.createElement("INPUT");
                        elto.setAttribute("type", "hidden");
                        elto.setAttribute("name", "_async");
                        elto.setAttribute("value", "1");
                        forms[i].appendChild(elto);
                        break;
                    }

                    break;
                }


            if (replace != null) {

                forms[i]._ajaxized = true;
                forms[i]._ajax_transition = this.onreadystateloading;

                if (forms[i].onsubmit)
                    forms[i]._onsubmit2 = forms[i].onsubmit

                forms[i].onsubmit = function() {
                    this.submit();
                    return false;
                }

                forms[i].submit = function() {

                    if (!this._onsubmit2 || this._onsubmit2() != false) {

                        var valores = new Array();
                        var idElemento = '';
                        var j = 0;

                        for (i = 0; i < this.elements.length; i++) {
                            var nombre = encodeURIComponent(this.elements[i].name);
                            if (nombre == '_asyncId')
                                idElemento = this.elements[i].value;

                            switch (this.elements[i].type) {

                                case 'select':
                                    if (isNaN(this.elements[i].selectedIndex)) {
                                        for (j = 0; j < this.elements[i].options.length; j++)
                                            if (this.elements[i].options[j].selected)
                                                valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i].options[j].value);
                                    }
                                    else if (this.elements[i].selectedIndex > -1)
                                        valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i].options[this.elements[i].selectedIndex].value);
                                    break;

                                case 'select-one':
                                    if (this.elements[i].selectedIndex > -1)
                                        valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i].options[this.elements[i].selectedIndex].value);
                                    break;

                                case 'select-multiple':
                                    for (j = 0; j < this.elements[i].options.length; j++)
                                        if (this.elements[i].options[j].selected)
                                            valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i].options[j].value);
                                    break;

                                case 'radio':
                                case 'checkbox':
                                    if (this.elements[i].length) {
                                        for (j = 0; j < this.elements[i].length; j++)
                                            if (this.elements[i][j].checked)
                                                valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i][j].value);
                                    }
                                    else if (this.elements[i].checked)
                                        valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i].value)
                                    break;

                                case 'text':
                                case 'textarea':
                                case 'password':
                                case 'hidden':
                                    valores[valores.length] = nombre + '=' + encodeURIComponent(this.elements[i].value)
                            }

                        }


//alert(scrollPos+' '+iReturnValue)

                        if (this.getAttribute("method").toUpperCase() == 'POST') {
                            var request = new XMLHttpRequest('POST', '.', true, null, null);

                            request.onchangereadystate = ajax_on_change_state;

                            request.onreadystatedone = ajax_replace_node;

                            request.onreadystateloading = this._ajax_transition;
                            request._loading_node_id = idElemento;

                            request.setRequestHeader("Content-Type",
                                    "application/x-www-form-urlencoded");

                            request.send(valores.join('&'));
                        }

                        else if (this.getAttribute("method").toUpperCase() == 'GET') {
                            var request = new XMLHttpRequest('GET', './?' + valores.join('&'), true, null, null);

                            request.onchangereadystate = ajax_on_change_state;

                            request.onreadystatedone = ajax_replace_node;

                            request.onreadystateloading = this._ajax_transition;
                            request._loading_node_id = idElemento;

                            request.send();
                        }
                        else
                            alert('Unknown method in form ' + this.id);

                    }

                }
            }

        }
}


XMLHttpRequest.prototype.onreadystateloading = null;
XMLHttpRequest.prototype.onreadystatedone = null;
XMLHttpRequest.prototype._loading_node_id = null;



//XMLHttpRequest.sendQueued
if (!window.onLoadArray) {
    window.onLoadArray = new Array();

    window.onLoadArray[window.onLoadArray.length] = window.onload;

    window.onload = function() {
        for (var i = 0; i < this.onLoadArray.length; i++)
            this.onLoadArray[i]();
    }
}

window.onLoadArray[window.onLoadArray.length] = function() {
    XMLHttpRequest.sendQueued();
}



IMHandler = new Object();
IMHandler.IMLast = null;
IMHandler.IMTime = null;
IMHandler.IMTimeout;
IMHandler.IMTimeoutTime = 2000;
IMHandler.IMRecoverTimeout;
IMHandler.aceptableMethods = new Object();

IMHandler.ajaxPull = function() {
    //pero si las respuesta tarda más de 60 segundos volvemos a restablecer el intervalo, suponiendo que se ha perdido la respuesta
    IMHandler.IMRecoverTimeout = setTimeout("clearTimeout(IMHandler.IMTimeout);IMHandler.IMTimeout=setTimeout('IMHandler.ajaxPull()',IMHandler.IMTimeoutTime);", 60000)

    var urlString = 'ajax/pull.php?IMTime=' + IMHandler.IMTime;
    var params = null;

    for (var prop in this.aceptableMethods) {
        params = this.aceptableMethods[prop]();

        for (var i = 0; i < params.length; i++)
            urlString += '&IMAccept[' + prop + '][]=' + params[i];

    }

    var request = new XMLHttpRequest('GET', urlString, true, null, null);

    request.onreadystatechange = ajax_on_change_state;
    request.onreadystatedone = function() {
        xml = this.responseXML;

        clearTimeout(IMHandler.IMRecoverTimeout);//esto no esta funcionando bien
        clearTimeout(IMHandler.IMTimeout);

        IMHandler.IMTime = xml.getElementsByTagName('IMTime')[0].childNodes[0].nodeValue;

        var grupos = xml.getElementsByTagName('IMGroup');
        var callback, imensajes, total = 0;

        for (var i = 0; i < grupos.length; i++) {
            eval('callback=' + grupos[i].getElementsByTagName('IMCallback')[0].childNodes[0].nodeValue + ';');
            imensajes = grupos[i].getElementsByTagName('IMessage');
            total += imensajes.length;
            callback(imensajes);
        }

        if (grupos.length == 0) {
            if (IMHandler.IMTimeoutTime < 15000)
                IMHandler.IMTimeoutTime = Math.round((1.2) * IMHandler.IMTimeoutTime);
        }
        else {
            /*
             //si tenemos
             IMHandler.IMTimeoutTime=(total/5)*IMHandler.IMTimeoutTime;
             //si recibimos menos de 5 reducimos pero si recivimos más de 5 aumentamos. No queremos estar actualizando seguido
             
             if(IMHandler.IMTimeoutTime<2000)
             IMHandler.IMTimeoutTime=2000; //Cada dos segundos
             else if(IMHandler.IMTimeoutTime>15000)
             IMHandler.IMTimeoutTime=15000;
             */

            if (total > 10) //si hay muchos mensajes tampoco quiero que se vuelva loca y prefiero tratarlos agrupados
                IMHandler.IMTimeoutTime = 5000
            else
                IMHandler.IMTimeoutTime = 2000
        }

        IMHandler.IMTimeout = setTimeout('IMHandler.ajaxPull()', IMHandler.IMTimeoutTime);
    }

    request.send();//cuando se llama aqui está descontextualizada
}

IMHandler.IMTimeout = setTimeout('IMHandler.ajaxPull()', IMHandler.IMTimeoutTime);
/*
 IMHandler.handleResponse=function(){
 xml=this.responseXML;
 
 clearTimeout(IMHandler.IMRecoverTimeout);//esto no esta funcionando bien
 clearTimeout(IMHandler.IMTimeout);
 
 IMHandler.IMTime=xml.getElementsByTagName('IMTime')[0].childNodes[0].nodeValue;
 
 var grupos=xml.getElementsByTagName('IMGroup');
 var callback, imensajes, total=0;
 
 for(var i=0; i<grupos.length; i++){
 eval('callback='+grupos[i].getElementsByTagName('IMCallback')[0].childNodes[0].nodeValue+';');
 imensajes=grupos[i].getElementsByTagName('IMessage');
 total+=imensajes.length;
 callback(imensajes);
 }
 
 if( grupos.length==0 ){
 if(IMHandler.IMTimeoutTime<15000)
 IMHandler.IMTimeoutTime=Math.round((1.2)*IMHandler.IMTimeoutTime);
 }
 else{
 /*
 //si tenemos
 IMHandler.IMTimeoutTime=(total/5)*IMHandler.IMTimeoutTime;
 //si recibimos menos de 5 reducimos pero si recivimos más de 5 aumentamos. No queremos estar actualizando seguido
 
 if(IMHandler.IMTimeoutTime<2000)
 IMHandler.IMTimeoutTime=2000; //Cada dos segundos
 else if(IMHandler.IMTimeoutTime>15000)
 IMHandler.IMTimeoutTime=15000;
 *   /
 
 if(total>10) //si hay muchos mensajes tampoco quiero que se vuelva loca y prefiero tratarlos agrupados
 IMHandler.IMTimeoutTime=5000
 else
 IMHandler.IMTimeoutTime=2000
 }
 
 IMHandler.IMTimeout=setTimeout('IMHandler.ajaxPull()',IMHandler.IMTimeoutTime);
 }
 */


